package com.app.micaihu.utils;

import android.text.TextUtils;

import com.app.micaihu.configure.AppConfigTools;
import com.app.micaihu.manager.UserInforManager;
import com.app.utils.util.AppTools;
import com.app.utils.util.StringUtils;
import com.app.utils.util.ToastUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Guo on 2017/1/8.
 * <p>
 * <p>
 * OkHTTP_3.0___________helper类
 */

public class OkHttp3Helper {


    private static OkHttp3Helper okHttp3Helper;
    private OkHttpClient mOkHttpClient;

    public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
    private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("image/jpg");

    private OkHttp3Helper() {
        if (mOkHttpClient == null) {
            initOkHttpClient();
        }
    }


    public static OkHttp3Helper getInstance() {
        if (okHttp3Helper == null) {
            okHttp3Helper = new OkHttp3Helper();

        }
        return okHttp3Helper;

    }


    /**
     * 初始化配置
     */
    private void initOkHttpClient() {
        File sdcache = new File(AppConfigTools.OKHTTPFloder);
        long cacheSize = 10 * 1024 * 1024;
        try {
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .connectTimeout(15L, TimeUnit.SECONDS)
                    .writeTimeout(20L, TimeUnit.SECONDS)
                    .readTimeout(20L, TimeUnit.SECONDS)
                    .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
            mOkHttpClient = builder.build();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传的--------主线程的回调
     */
    public static abstract class OnUploadResponseCallBack {

        public void onStart() {
        }


        public void onFailure() {
        }


        public void onSucess(Response response) {
        }


    }



    /**
     * 下载的--------主线程的回调
     */
    public static abstract class OnDownLoadResponCallBack {

        public void onStart() {
        }


        public void onFailure() {
        }


        public void onSucess(File file) {
        }


    }

    /**
     * 异步下载
     * 如果缓存有则直接返回
     */
    public void downAsynFile_Cache(final String url, final String targetDir, final String fileName, final OnDownLoadResponCallBack onDownLoadResponCallBack) {
        if(TextUtils.isEmpty(url)){
            ToastUtils.showText("下载链接为空,下载失败");
            if (onDownLoadResponCallBack != null) {
                onDownLoadResponCallBack.onFailure();
            }
            return;
        }
        //检查该文件是否存在
        File file = new File(targetDir+File.separator+fileName);
        if(file.exists()){
            if (onDownLoadResponCallBack != null) {
                onDownLoadResponCallBack.onSucess(file);
            }
            return;
        }
        if (onDownLoadResponCallBack != null) {
            onDownLoadResponCallBack.onStart();
        }
        Request request;
        try {
            request = new Request.Builder().url(url).build();
        } catch (Exception e) {
            e.printStackTrace();
            if (onDownLoadResponCallBack != null) {
                onDownLoadResponCallBack.onFailure();
            }
            return;
        }
        mOkHttpClient.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                if (onDownLoadResponCallBack != null) {
                    onDownLoadResponCallBack.onFailure();
                }
            }

            @Override
            public void onResponse(Call call, Response response) {
                InputStream inputStream = response.body().byteStream();
                FileOutputStream fileOutputStream = null;
                File dir = new File(targetDir);
                if(!dir.exists()) {
                    dir.mkdirs();
                }
                File file;
                try {
                    file = new File(dir,fileName);
                    fileOutputStream = new FileOutputStream(file);
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.flush();

                    if (onDownLoadResponCallBack != null) {
                        onDownLoadResponCallBack.onSucess(file);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    if (onDownLoadResponCallBack != null) {
                        onDownLoadResponCallBack.onFailure();
                    }
                }finally {
                    try {
                        if(inputStream != null){
                            inputStream.close();
                        }
                        if(fileOutputStream != null){
                            fileOutputStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
        });
    }

    /**
     * 异步下载
     */
    public void downAsynFile(final String url, final String targetDir, final String fileName, final OnDownLoadResponCallBack onDownLoadResponCallBack) {
        if(TextUtils.isEmpty(url)){
            ToastUtils.showText("下载链接为空,下载失败");
            return;
        }
        if (onDownLoadResponCallBack != null) {
            onDownLoadResponCallBack.onStart();
        }
        Request request = null;
        try {
            request = new Request.Builder().url(url).build();
        } catch (Exception e) {
            e.printStackTrace();
            ToastUtils.showText("下载链接有误,下载失败");
            return;
        }
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (onDownLoadResponCallBack != null) {
                    onDownLoadResponCallBack.onFailure();

                }
            }


            @Override
            public void onResponse(Call call, Response response) {
                InputStream inputStream = response.body().byteStream();
                FileOutputStream fileOutputStream = null;
                File dir = new File(targetDir);
                if(!dir.exists()) {
                    dir.mkdirs();
                }
                File file;
                try {
                    file = new File(dir,fileName);
                    fileOutputStream = new FileOutputStream(file);
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.flush();

                    if (onDownLoadResponCallBack != null) {
                        onDownLoadResponCallBack.onSucess(file);

                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        if(inputStream != null){
                            inputStream.close();
                        }
                        if(fileOutputStream != null){
                            fileOutputStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
        });
    }


    /**
     * 异步上传 单个 文件
     */
    public void uploadAsynFile(String url, File file, HashMap<String, String> hashMap, final OnUploadResponseCallBack OnUploadResponseCallBack) {
        if (OnUploadResponseCallBack != null) {
            OnUploadResponseCallBack.onStart();
        }

        RequestBody requestBody = UploadMD5Encryption(hashMap, file);
        Request request = new Request.Builder()
                .url(url)
                .addHeader("token", UserInforManager.getInstance().getUserInfor().getToken())//token
                .addHeader("cv", AppTools.getVersionName())//头
                .post(requestBody)
                .build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (OnUploadResponseCallBack != null) {
                    OnUploadResponseCallBack.onFailure();
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (OnUploadResponseCallBack != null) {
                    OnUploadResponseCallBack.onSucess(response);
                }
            }
        });
    }


    /**
     * 上传图片 的加密方法
     * @param params
     * @param file
     * @return
     */
    public static RequestBody UploadMD5Encryption( HashMap<String, String> params, File file) {

        MultipartBody.Builder builder = new MultipartBody.Builder();
        RequestBody fileBody = RequestBody.create(MEDIA_TYPE_JPG, file);
        builder.setType(MultipartBody.FORM)
                .addPart(Headers.of(
                        "Content-Disposition",
                        "form-data; name=\"filename\"; filename=\"" + file.getName() + "\""), fileBody);

        Object[] key = params.keySet().toArray();
        if (key.length == 0) {
            return null;
        }
        Arrays.sort(key);//升序排列
        //待加密字符串
        StringBuffer verifyMsg = new StringBuffer();
        //倒序输出
        try {
            for (int i = key.length - 1; i >= 0; i--) {
                builder.addFormDataPart(key[i].toString(), params.get(key[i]));
                verifyMsg.append(key[i] + "=" + URLEncoder.encode(params.get(key[i]).toString(), "utf-8") + "&");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //拼接版本标识
        verifyMsg.append(AppConfigTools.APICODE);
        //进行MD5加密
        String verifyMsgMd5 = StringUtils.md5(verifyMsg.toString());
        builder.addFormDataPart("verifyMsg", verifyMsgMd5);

        return builder.build();


    }


    public OkHttpClient getOkHtp(){
        return mOkHttpClient;
    }





}
